#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"

char* get_name(char *path){
    char *p;
    for(p = path+strlen(path); p >= path && *p !='/'; p--);
    p++;
    return p;
}


void find(char *path, char *str){
    char buf[512], *p;
    int fd;
    struct dirent de;   // Directory is a file containing a sequence of dirent structures
    struct stat st;     // file sturcture

    fd = open(path, 0); //  Open a file; flags indicate read/write; returns an fd (file descriptor).
    if (fd<0) {
        fprintf(2, "ERROR: find() - cannot open()");
        return;
    }
    if (fstat(fd, &st) < 0) {    //  Place info about an open file into *st. 
        fprintf(2,"ERROR: find() - cannot fstat()");
        close(fd);
        return;
    }
    switch(st.type){
        case T_DEVICE:
        case T_FILE:
            if (!strcmp(str, get_name(path))) {
                printf("%s\n",path);
            }
            break;
        case T_DIR:
            strcpy(buf,path);
            p = buf + strlen(buf);
            *p = '/';
            p++;
            while(read(fd, &de, sizeof de) == sizeof de){//使用read从目录文件中读取目录条目，处理目录中文件
                if(de.inum == 0)//该目录条目为空或未使用
                    continue;
                memmove(p, de.name, DIRSIZ);
                p[DIRSIZ] = 0;
                if(stat(buf, &st) < 0){//通过文件路径将对应的文件信息放入文件结构体stat中，若失败则返回-1
                    printf("ls: cannot stat %s\n", buf);
                    continue;
                }
                if(st.type == T_DEVICE || st.type == T_FILE){//判断为非目录文件
                    if(!strcmp(str, get_name(buf)))
                        printf("%s\n",buf);
                }
                else if(st.type == T_DIR && strcmp(".", get_name(buf)) && strcmp("..", get_name(buf)))//判定为子目录，递归处理，注意不要重复进入本目录以及父目录
                    find(buf, str);
            }
            break;
    }
    close(fd);
    return;
}

int main(int argc, char *argv[]){ 
    if (argc == 3) {
        find(argv[1], argv[2]);
    }else {
        fprintf(2,"Usage: find [a b]");
    }
    exit(0);
}